package com.card.client.view;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.card.client.dialog.DeleteDialog;
import com.card.client.dialog.EditCreditCardBillDialog;
import com.card.client.dialog.ShowCreditCardBillInfoDialog;
import com.card.client.entry.CreditCard;
import com.card.client.entry.CreditCardBill;
import com.card.client.entry.Util;
import com.card.client.entry.ViewObject;
import com.card.client.service.CreditCardBillService;
import com.card.client.service.CreditCardBillServiceAsync;
import com.card.client.service.CreditCardService;
import com.card.client.service.CreditCardServiceAsync;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

public class CreditCardBillInfoView extends Composite implements ViewObject {
	
	private static CreditCardViesUiBinder uiBinder = GWT.create(CreditCardViesUiBinder.class);

	interface CreditCardViesUiBinder extends UiBinder<Widget, CreditCardBillInfoView> {
	}

	private final CreditCardServiceAsync ccs = GWT.create(CreditCardService.class);
	
	private final CreditCardBillServiceAsync ccbs = GWT.create(CreditCardBillService.class);

	private Grid grid = getGrid();

	@UiField HorizontalPanel table;
	
	@UiField ListBox financeMonth;

	@UiField Button addCreditCardBill;

	@UiField Label descript;

	@UiField HTML sum;

	private int total;
	
	private int minRePay;
	
	private int actualRePay;
	
	private int overAmount;
	
	private int interst;
	
	private int overCost;
	
	private int excess;
	
	private int takeAmount;

	private String[] title = CreditCardBill.title;
	
	private List<CreditCard> cardType = new ArrayList<CreditCard>();
	
	private CreditCardBill tempCreditCardBill;
	
	private boolean edit = false;
	
	private Long tempId;
	
	private String[] financeMonthList;
	
	public CreditCardBillInfoView() {
		initWidget(uiBinder.createAndBindUi(this));
		table.setWidth("100%");
		table.add(grid);
		grid.setWidth("100%");
		descript.setStyleName("descript");
		TableAction action = new TableAction();
		action.setCreditCardBillInfoView(this);
		grid.addClickHandler(action);
		sum.setWidth("100%");
		sum.setStyleName("sum");
		financeMonth.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				int index = financeMonth.getSelectedIndex();
				String value = financeMonth.getItemText(index);
				onLoad(value);
			}
		});
	}

	public void onLoad(String fMonth) {
		ccs.getAllCard(new AsyncCallback<CreditCard[]>() {
			public void onSuccess(CreditCard[] result) {
				for(int i=0;i<result.length;i++){
					cardType.add(result[i]);
				}
			}
			public void onFailure(Throwable caught) {}
		});
		
		setFinanceMonthList();
		
		ccbs.getFinanceMonthCreditCardBill(fMonth, new AsyncCallback<CreditCardBill[]>() {
			public void onSuccess(CreditCardBill[] result) {
				if (result != null) {
					total = 0;
					minRePay = 0;
					actualRePay = 0;
					overAmount = 0;
					interst = 0;
					overCost = 0;
					excess = 0;
					takeAmount = 0;
					setData(result);
					String sumText = "合计：最低还款额：" + Util.intToStr(minRePay);
					sumText = sumText + "元 / 实际还款额：" + Util.intToStr(actualRePay);
					sumText = sumText + "元 / 超限费：" + Util.intToStr(overAmount);
					sumText = sumText + "元 / 利息：" + Util.intToStr(interst);
					sumText = sumText + "元 / 手续费：" + Util.intToStr(overCost);
					sumText = sumText + "元 / 余额：" + Util.intToStr(excess);
					sumText = sumText + "元 / 可用余额：" + Util.intToStr(total);
					sumText = sumText + "元 / 套取金额：" + Util.intToStr(takeAmount) + "元";
					sum.setText(sumText);
				}
			}
			public void onFailure(Throwable caught) {}
		});
	}

	private void setFinanceMonthList() {
		ccbs.getAllCreditCardBill(new AsyncCallback<CreditCardBill[]>() {
			public void onSuccess(CreditCardBill[] result) {
				ArrayList<String> temp = new ArrayList<String>();
				if(result.length>0){
					for(int i=0;i<result.length;i++){
						CreditCardBill ccb = result[i];
						boolean add = true;
						if(temp.isEmpty()){
							temp.add(ccb.getFinanceMonth());
							add = false;
						} else {
							for(int a=0;a<temp.size();a++){
								String fm = temp.get(a);
								if(fm.equals(ccb.getFinanceMonth())){
									add = false;
									break;
								}
							}
						}
						if(add){
							temp.add(ccb.getFinanceMonth());
						}
					}
					financeMonthList = new String[temp.size()];
					for(int i=0;i<financeMonthList.length;i++){
						financeMonthList[i] = temp.get(i);
					}
				} else {
					financeMonthList = new String[1];
					DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("yyyy-MM");
					String thisMonth = dateTimeFormat.format(new Date());
					financeMonthList[0] = thisMonth;
				}
				int count = financeMonth.getItemCount();
				for(int i=0;i<financeMonthList.length;i++){
					boolean add = true;
					for(int a=0;a<count;a++){
						String value = financeMonth.getItemText(a);
						if(value.equals(financeMonthList[i])){
							add = false;
							break;
						}
					}
					if(add){
						financeMonth.addItem(financeMonthList[i]);
					}
				}
			}
			public void onFailure(Throwable caught) {}
		});
	}

	private void setData(CreditCardBill[] result) {
		if (result.length == 0) {
			grid.resize(1, title.length);
		} else {
			grid.resize(result.length + 1, title.length);
		}
		for(int i=0;i<title.length;i++){
			if(i==0){
				grid.getColumnFormatter().setWidth(i, "5%");
			} else if (i == 1){
				grid.getColumnFormatter().setWidth(i, "13%");
			} else {
				grid.getColumnFormatter().setWidth(i, "9%");
			}
		}
		for (int i = 0; i < title.length; i++) {
			grid.setText(0, i, title[i]);
			if (i != (title.length - 1)) {
				grid.getCellFormatter().addStyleName(0, i, "header");
			} else {
				grid.getCellFormatter().addStyleName(0, i, "header-n");
			}
		}
		for (int i = 0; i < result.length; i++) {
			int b = 0;
			CreditCardBill ccb = result[i];
			grid.setText(i + 1, b++, Long.toString(ccb.getId()));
			for(int a=0;a<cardType.size();a++){
				CreditCard cc = cardType.get(a);
				if(cc.getItem().equals(result[i].getItem())){
					grid.setText(i + 1, b++, cc.getName());
					break;
				}
			}
			grid.setText(i + 1, b++, DateTimeFormat(ccb.getLastRePayDate()));
			grid.setText(i + 1, b++, DateTimeFormat(ccb.getRePayDate()));
			grid.setText(i + 1, b++, Util.intToStr(ccb.getMinRePay()) + "元");
			grid.setText(i + 1, b++, Util.intToStr(ccb.getActualRePay()) + "元");
			grid.setText(i + 1, b++, Util.intToStr(ccb.getOverAmount() + ccb.getInterest() + ccb.getOverCost()) + "元");
			grid.setText(i + 1, b++, Util.intToStr(ccb.getActualRePay() + ccb.getExcess() - ccb.getTakeAmount()) + "元");
			total = total + ccb.getActualRePay() + ccb.getOverAmount();
			minRePay = minRePay + ccb.getMinRePay();
			actualRePay = actualRePay + ccb.getActualRePay();
			overAmount = overAmount + ccb.getOverAmount();
			interst = interst + ccb.getInterest();
			overCost = overCost + ccb.getOverCost();
			excess = excess + ccb.getExcess();
			takeAmount = takeAmount + ccb.getTakeAmount();
			reload(i + 1);
		}
	}

	private String DateTimeFormat(Date date){
		if(null == date){
			return "";
		}
		DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("yyyy-MM-dd");
		return dateTimeFormat.format(date);
	}
	
	public void show() {

	}

	public Grid getGrid() {
		if (grid != null) {
			return grid;
		}
		return new GreenMouseEventGrid();
	}

	@UiHandler("addCreditCardBill")
	void onClick(ClickEvent e) {
		 EditCreditCardBillDialog acbd = new EditCreditCardBillDialog("添加信用卡账目", "添加一条信用卡账目", this, null, EditCreditCardBillDialog.ADD);
		 acbd.center();
		 acbd.show();
	}

	private void reload(int row) {
		descript.setText(null);
		if (row % 2 != 0) {
			for(int i=0;i<title.length;i++){
				if(i == title.length-1){
					grid.getCellFormatter().setStyleName(row, i, "row0-n");
				} else {
					grid.getCellFormatter().setStyleName(row, i, "row0");
				}
			}
		} else {
			for(int i=0;i<title.length;i++){
				if(i == title.length-1){
					grid.getCellFormatter().setStyleName(row, i, "row1-n");
				} else {
					grid.getCellFormatter().setStyleName(row, i, "row1");
				}
			}
		}
	}

	class GreenMouseEventGrid extends MouseEventGrid {

		public void onMouseOut(Element td, int row) {
			reload(row);
		}

		public void onMouseOver(Element td, int row) {
			Element tr = DOM.getParent(td);
			int column = DOM.getChildIndex(tr, td);
			String name = grid.getHTML(row, 1);
			if (column == 0) {
				descript.setText("删除账目 “" + name + "” ");
			} else if (column == 1) {
				descript.setText("查看账目 “" + name + "” 信息");
			} else {
				descript.setText("修改账目 “" + name + "” 信息");
			}
			for(int i=0;i<title.length;i++){
				if(i == title.length-1){
					grid.getCellFormatter().setStyleName(row, i, "rows-n");
				} else {
					grid.getCellFormatter().setStyleName(row, i, "rows");
				}
			}
		}
	}

	EditCreditCardBillDialog ecd = null;
	
	public class TableAction implements ClickHandler {

		private CreditCardBillInfoView creditCardBillInfoView;

		public void onClick(ClickEvent event) {
			HTMLTable table = (HTMLTable) event.getSource();
			Cell Mycell = table.getCellForEvent(event);
			if (Mycell == null)
				return;
			int row = Mycell.getRowIndex();
			int col = Mycell.getCellIndex();
			reload(row);
			String tid = grid.getHTML(row, 0);
			tempId = Long.valueOf(tid);
			getObject();
			Long id = Long.valueOf(grid.getHTML(row, 0));
			if (col == 0) {
				String des = "确认删除账目 “" + grid.getHTML(row, 1) + "” 么？";
				DeleteDialog dd = new DeleteDialog("账目", des, creditCardBillInfoView,	id);
				dd.show();
			} else if (col == 1) {
				if(null == tempCreditCardBill){
					return;
				}
				String[] content = new String[12];
				content[0] = grid.getHTML(row, 1);
				content[1] = tempCreditCardBill.getFinanceMonth();
				content[2] = grid.getHTML(row, 2);
				content[3] = grid.getHTML(row, 3);
				content[4] = grid.getHTML(row, 4);
				content[5] = grid.getHTML(row, 5);
				content[6] = Util.intToStr(tempCreditCardBill.getOverAmount());
				content[7] = Util.intToStr(tempCreditCardBill.getInterest());
				content[8] = Util.intToStr(tempCreditCardBill.getOverCost());
				content[9] = Util.intToStr(tempCreditCardBill.getExcess());
				content[10] = Util.intToStr(tempCreditCardBill.getTakeAmount());
				content[11] = DateTimeFormat(tempCreditCardBill.getTakeDate());
				String desc = "查看账目\"" + grid.getHTML(row, 1) + "\"的详细信息";
				ShowCreditCardBillInfoDialog scbid = new ShowCreditCardBillInfoDialog("查看详情", desc, content);
				scbid.show();
			} else {
				if(!edit){
					edit = true;
				}
				String des = "修改账目 “" + grid.getHTML(row, 1) + "” 的信息";
				ecd = new EditCreditCardBillDialog("修改账目信息",	des, creditCardBillInfoView, tempCreditCardBill, EditCreditCardBillDialog.UPDATE);
				ecd.show();
			}
		}

		public void setCreditCardBillInfoView(CreditCardBillInfoView creditCardBillInfoView) {
			this.creditCardBillInfoView = creditCardBillInfoView;
		}
	}

	public void delDate(Long id) {
		if (id == null) {
			return;
		}
		ccbs.delCreditCardBill(id, new AsyncCallback<Void>() {
			public void onSuccess(Void result) {
				onLoad();
			}

			public void onFailure(Throwable caught) {
			}
		});
	}

	private void getObject() {
		ccbs.getAllCreditCardBill(new AsyncCallback<CreditCardBill[]>() {
			public void onSuccess(CreditCardBill[] result) {
				for(int i=0;i<result.length;i++){
					if(result[i].getId().equals(tempId)){
						tempCreditCardBill = result[i];
						if(edit){
							edit = false;
							ecd.setCreditCardBill(tempCreditCardBill);
						}
						break;
					}
				}
			}
			public void onFailure(Throwable caught) {}
		});
	}
}
